package com.sc.security.service.impl;

import com.google.common.base.Preconditions;
import com.sc.security.beans.LogService;
import com.sc.security.common.RequestHolder;
import com.sc.security.dao.SysAclModuleMapper;
import com.sc.security.exception.ParamException;
import com.sc.security.model.SysAclModule;
import com.sc.security.model.SysDept;
import com.sc.security.service.AclModuleService;
import com.sc.security.utils.BeanValidator;
import com.sc.security.utils.IpUtil;
import com.sc.security.utils.LevelUtil;
import com.sc.security.vo.AclModuleVo;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class AclModuleServiceImpl implements AclModuleService {
    @Autowired
    private SysAclModuleMapper aclModuleMapper;
    @Autowired
    private LogService logService;
    @Override
    public void save(AclModuleVo aclModuleVo) {
        BeanValidator.check(aclModuleVo);
        if (checkExist(aclModuleVo.getParentId(),aclModuleVo.getName(),aclModuleVo.getId())){
            throw new ParamException("同一层级下存在名称相同的权限");
        }
        SysAclModule aclModule = new SysAclModule();
        BeanUtils.copyProperties(aclModuleVo,aclModule);
        aclModule.setLevel(LevelUtil.calculateLevel(getLevel(aclModuleVo.getParentId()),aclModuleVo.getParentId()));
        aclModule.setOperator(RequestHolder.getCurrentUser().getUsername());
        aclModule.setOperateIp(IpUtil.getUserIP(RequestHolder.getCurrentRequest()));
        aclModule.setId(null);
        aclModuleMapper.insertSelective(aclModule);
        logService.saveModuleAcl(null,aclModule);
    }

    @Override
    public void update(AclModuleVo aclModuleVo) {
        BeanValidator.check(aclModuleVo);
        if (checkExist(aclModuleVo.getParentId(),aclModuleVo.getName(),aclModuleVo.getId())){
            throw new ParamException("同一层级下存在名称相同的权限");
        }
        SysAclModule before = aclModuleMapper.selectByPrimaryKey(aclModuleVo.getId());
        Preconditions.checkNotNull(before,"待更新项目不存在");
        SysAclModule after = new SysAclModule();
        BeanUtils.copyProperties(aclModuleVo,after);
        after.setOperator(RequestHolder.getCurrentUser().getUsername());
        after.setOperateIp(IpUtil.getUserIP(RequestHolder.getCurrentRequest()));
        after.setLevel(LevelUtil.calculateLevel(getLevel(aclModuleVo.getParentId()),aclModuleVo.getParentId()));
        updateWithChild(before,after);
    }
    @Transactional
    public void updateWithChild(SysAclModule before,SysAclModule after){

        String nextLevelPrefix = after.getLevel();
        String oldLevelPrefix = before.getLevel();
        if(!nextLevelPrefix.equals(oldLevelPrefix)){
            List<SysAclModule> list = aclModuleMapper.getChildDeptListByLevel(before.getLevel()+"."+before.getId()+"%");
            if(CollectionUtils.isNotEmpty(list)){
                for(SysAclModule module:list){
                    String level = module.getLevel();
                    if(level.indexOf(oldLevelPrefix)==0){
                        level = nextLevelPrefix+level.substring(oldLevelPrefix.length());
                        module.setLevel(level);
                    }
                }
                aclModuleMapper.batchUpdateLevel(list);
            }
        }
        aclModuleMapper.updateByPrimaryKey(after);
        logService.saveModuleAcl(before,after);
    }
    @Override
    public void delete(Integer id) {
        SysAclModule module = aclModuleMapper.selectByPrimaryKey(id);
        if(module==null){
            throw new ParamException("不存在此部门");
        }
        deleteWithChild(module);
    }

    @Transactional
    public void deleteWithChild(SysAclModule module) {
        List<SysAclModule> moduleList = aclModuleMapper.getChildDeptListByLevel(module.getLevel()+"."+module.getId());
        if(CollectionUtils.isNotEmpty(moduleList)){
            for(SysAclModule mod:moduleList){
                aclModuleMapper.deleteByPrimaryKey(mod.getId());
            }
        }
        aclModuleMapper.deleteByPrimaryKey(module.getId());
    }

    @Override
    public void acls(Integer id) {

    }




    private boolean checkExist(Integer parentId,String aclName,Integer aclId){
        int count = aclModuleMapper.countByNameAndParentId(parentId,aclName,aclId);
        if(count>0){
            return true;
        }
        return false;
    }
    private String getLevel(Integer aclModuleId){
        SysAclModule module = aclModuleMapper.selectByPrimaryKey(aclModuleId);
        if(module==null){
            return null;
        }
        return module.getLevel();
    }
}
